/*
    Priscilla - A library for enocean network access
    Copyright (C) 2012-2013 B. Aigner / R. Wagner

    This program is free software; you can redistribute it and/or 
    modify it under the terms of the GNU General Public License 
    as published by the Free Software Foundation; either version 2 
    of the License, or at your option any later version. 
 
    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    GNU General Public License for more details. 
 
    You should have received a copy of the GNU General Public License 
    along with this program; if not, write to the Free Software 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. 
 
    Linking this library statically or dynamically with other modules is 
    making a combined work based on this library. Thus, the terms and 
    conditions of the GNU General Public License cover the whole 
    combination. 
 
    As a special exception, the copyright holders of this library give you 
    permission to link this library with independent modules to produce an 
    executable, regardless of the license terms of these independent 
    modules, and to copy and distribute the resulting executable under terms 
    of your choice, provided that you also meet, for each linked independent 
    module, the terms and conditions of the license of that module. An 
    independent module is a module which is not derived from or based on 
    this library. If you modify this library, you may extend this exception 
    to your version of the library, but you are not obligated to do so. If 
    you do not wish to do so, delete this exception statement from your 
    version. 
*/

package at.technikum_wien.embsys.aat.PriscillaCore.link;

import at.technikum_wien.embsys.aat.PriscillaCore.enums.BinaryState;
import at.technikum_wien.embsys.aat.PriscillaCore.enums.ErrorCodeLRN;
import at.technikum_wien.embsys.aat.PriscillaCore.enums.ErrorCodeSend;
import at.technikum_wien.embsys.aat.PriscillaCore.enums.EventSend;
import at.technikum_wien.embsys.aat.PriscillaCore.enums.FanState;
import at.technikum_wien.embsys.aat.PriscillaCore.enums.FanType;
import at.technikum_wien.embsys.aat.PriscillaCore.link.event.LinkListener;
import at.technikum_wien.embsys.aat.PriscillaCore.telegram.Telegram;

/**
 * Interface definition for an Enocean link
 * 
 * Every link have to implement different functions for sending events
 * and for manipulating the device database manually.
 * 
 * @author R. Wagner
 */
public interface EnOceanLink {

	int mode = 0;
	
	/**
	 * Add a new event subscriber to the list
	 * @param l LinkListener instance with implemented event methods
	 */
	void addLinkListener(LinkListener l);

	/**
	 * Send a telegram only with the telegram instance
	 * 
	 * @param data Telegram instance, filled with the necessary information
	 * @return ErrorCodeSend
	 */
	ErrorCodeSend sendTelegram(Telegram data);
	
	/**
	 * Send an event
	 * 
	 * Send an event with the given type. This method is usable for all
	 * events, except Binary and Fan events (these are using different data)
	 * 
	 * @param event Type of event
	 * @param deviceNr Address for sending (the gateway provides 127 different addresses, the number is combined with the device ID of the gateway)
	 * @param data Data which should be send with the event, e.g. temperature, illumination, ...
	 * @return ErrorCodeSend
	 */
	ErrorCodeSend sendEvent(EventSend event, int deviceNr, float data);
	
	/**
	 * Send an event
	 * 
	 * Send an event with the given type. This method is only for BinaryEvents 
	 * 
	 * @param event Type of event (must be BinaryEvent)
	 * @param deviceNr Address for sending (the gateway provides 127 different addresses, the number is combined with the device ID of the gateway)
	 * @param channelA Binary channel A
	 * @param channelB Binary channel B
	 * @param channelC Binary channel C
	 * @param channelD Binary channel D
	 * @return ErrorCodeSend
	 */
	ErrorCodeSend sendEvent(EventSend event, int deviceNr, BinaryState channelA, BinaryState channelB, BinaryState channelC, BinaryState channelD);
	
	/**
	 * Send an event
	 * 
	 * Send an event with the given type. This method is only for FanEvents 
	 * 
	 * @param event Type of event (must be FanEvent)
	 * @param deviceNr Address for sending (the gateway provides 127 different addresses, the number is combined with the device ID of the gateway)
	 * @param fanstate State of the fan 
	 * @param fantype Either 3 or 5 fan states
	 * @return ErrorCodeSend
	 */
	ErrorCodeSend sendEvent(EventSend event, int deviceNr, FanState fanstate, FanType fantype);
	
	/**
	 * Add a device manually
	 * 
	 * This method adds a device to the list and the XML file. It is used
	 * for providing TYPE and FUNC manually, if the learn-in telegram of
	 * a sensor does not provide them.
	 * 
	 * @param func FUNC field for the sensor
	 * @param type TYPE field for the sensor
	 * @param deviceID Device ID of the sensor
	 * @return ErrorCodeLRN
	 */
	ErrorCodeLRN addDeviceManually(int func, int type, String deviceID);
	
	/**
	 * Modify a device manually
	 * 
	 * This method modifies a device from the list and the XML file.
	 * 
	 * @param func New FUNC field for the sensor
	 * @param type New TYPE field for the sensor
	 * @param deviceID Device ID of the sensor
	 * @return ErrorCodeLRN
	 */
	ErrorCodeLRN modifiyDeviceManually(int func, int type, String deviceID);
	
	/**
	 * Remove a device manually
	 * 
	 * This method removes a device from the list and the XML file.
	 * 
	 * @param deviceID Device ID of the sensor
	 * @return ErrorCodeLRN
	 */
	ErrorCodeLRN removeDeviceManually(String deviceID);
}
